﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Plotter
{
    class PositionMapper
    {
        private int _step_width;
        private int _step_height;

        private double scew_factor = 0.6;
        private double x_offset = 5000;
        private double y_offset = 5000;


        /// <summary>
        /// Hilfsklasse zur Umrechnung von Pixel in Schrittpositionen
        /// </summary>
        public PositionMapper(int step_width, int step_height, double scew_factor)
        {
            this._step_width = step_width;
            this._step_height = step_height;
            this.scew_factor = scew_factor;
        }

        /// <summary>
        /// Rechnet die Pixel in Schrittpositionen um
        /// </summary>
        /// <param name="points">Punkte welche gemappt werden</param>
        /// <returns>Gemappte Positionen</returns>
        public Point[] Map(Point[] points)
        {
            List<Point> temp = new List<Point>();

            Rectangle rectangle = this.OuterRectangle(points);
            double x_ratio = (this.scew_factor * (this._step_width - this.x_offset - 1000)) / rectangle.Width;
            double y_ratio = (this.scew_factor * (this._step_height - this.y_offset - 1000)) / rectangle.Height;
            double lower_ratio = Math.Min(x_ratio, y_ratio);

            foreach (Point p in points)
            {
                //Rechnet einen zehntel Abstand dazu
                double x = (double)p.X * lower_ratio + this.x_offset;
                double y = (double)p.Y * lower_ratio + this.y_offset;
                temp.Add(new Point((int)x, (int)y));
            }
            return temp.ToArray();
        }

        /// <summary>
        /// Liefert das Rechteck, welches alle Punkte umgibt
        /// </summary>
        /// <param name="points">Die Punkte</param>
        /// <returns>Umschliessendes Rechteck</returns>
        private Rectangle OuterRectangle(Point[] points)
        {
            int min_x = points.Min((p) => { return p.X; });
            int min_y = points.Min((p) => { return p.Y; });
            int max_x = points.Max((p) => { return p.X; });
            int max_y = points.Max((p) => { return p.Y; });

            return new Rectangle(new Point(min_x, min_y), new Size(max_x - min_x, max_y - min_y));
        }
    }
}
